export type PairType = {
	first: any;
	second: any;
}

export const pair = (first: any) => (second: any) => {
	return {
		first,
		second
	}
}

export const fst = (p: PairType) => p.first
export const snd = (p: PairType) => p.second

export const head = fst
export const tail = snd

export function list2array(xs: PairType) {
	let result: any[] = [];
	while (xs !== null) {
		result.push(head(xs));
		xs = tail(xs);
	}
	return result;
}

export function array2list(arrayLike: Iterable<undefined> | ArrayLike<unknown>) {
	let result: PairType | null = null;
	let xs = Array.from(arrayLike).reverse();
	for (let it of xs) {
			result = pair (it) (result);
	}
	return result;
}

export const range: any = (low: number) => (high: number) => 
	low > high
	? null
	: pair (low) (range (low + 1) (high));

export const map: any = (f: Function) => (xs: PairType) =>
	xs === null
	? null
	: pair (f (head (xs))) (map (f) (tail (xs)));